﻿#include <iostream>

using namespace std;
using std::cout;
using std::endl;

template<typename... T>
void demo1(T... args) {
    cout << sizeof...(args) << endl;
}

// @note 递归终止函数
// void print() {
//     cout << "empty" << endl;
// }
template<typename T>
void print(T t) {
    cout << "parameter " << t << endl;
}

// @note 展开函数
template<typename T, typename... Args>
void print(T head, Args... rest) {
    cout << "parameter " << head << endl;
    print(rest...);
}

// 求和 C++11
template<typename T>
T sum(T t) {
    return t;
}

template<typename T, typename... Types>
T sum(T first, Types... rest) {
    return first + sum<T>(rest...);
}

// 求和C++17
template<class... Ts>
auto sum17(Ts ... args)
{
    return (args + ...);
}

template<typename T>
void printArg(T t) {
    cout << t << endl;
}

// 借助「逗号表达式」和「初始化列表」，不通过递归方式来展开参数包
// (printArg(args), 0) 表达式的值是0
template<typename... Args>
void expand(Args... args) {
    int arr[] = { (printArg(args), 0)... };
    // 展开后 {((printArg(arg1), 0), (printArg(arg2), 0), (printArg(arg3), 0),  ... ,(printArg(arg_N), 0))}
}

void Testdemo1()
{
    demo1();        // 0
    demo1(1, 2);    // 2
    demo1(1, 2, "");// 3
}

void TestSum()
{
    cout << (0 == sum(0)) << '\n';
    cout << (1 == sum(1)) << '\n';
    cout << (3 == sum(1, 2)) << '\n';
    cout << (6 == sum(1, 2, 3)) << '\n';
    cout << (10 == sum(1, 2, 3, 4)) << '\n';

    // sum17();  //编译不过去
    cout << (0 == sum17(0)) << '\n';
    cout << (1 == sum17(1)) << '\n';
    cout << (3 == sum17(1, 2)) << '\n';
    cout << (6 == sum17(1, 2, 3)) << '\n';
    cout << (10 == sum17(1, 2, 3, 4)) << '\n'; 
}


// 编译期求阶乘
template<int N>
class F {
public:
    enum {
        res = N * F<N - 1>::res
    };
};

//递归终止条件
template<>
class F<1> {
public:
    enum {
        res = 1
    };
};
 

int main(int argc, char const* argv[])
{
    cout << F<4>::res << endl; // 24 = 1*2*3*4
    // Testdemo1();
    // print(1, 2, 3, 4);
    expand(1, 2, 3, 4);

    // TestSum();
    return 0;
}
